﻿//++
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
// Module Name:
//
//  DispatcherTest.cs
//    
// Abstract:
//
//  Unit tests for the DispatcherHelpers class.
//  
//--

using System;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace Microsoft.EnhancedReminders.Dispatcher.UnitTests
{   
    /// <summary>
    ///This is a test class for DispatcherHelpersTest and is intended
    ///to contain all DispatcherHelpersTest Unit Tests
    ///</summary>
    [TestClass()]
    public class DispatcherHelpersTest
    {


        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        //[ClassInitialize()]
        //public static void MyClassInitialize(TestContext testContext)
        //{
        //}
        //
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        //[TestInitialize()]
        //public void MyTestInitialize()
        //{
        //}
        //
        //Use TestCleanup to run code after each test has run
        //[TestCleanup()]
        //public void MyTestCleanup()
        //{
        //}
        //
        #endregion

        /// <summary>
        /// Test a reminder for right now
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanNow()
        {
            string expected = string.Format(CultureInfo.CurrentUICulture, IMResources.LeadTime_Present,
                TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, TimeZoneInfo.Local).ToShortTimeString());
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, DateTime.UtcNow, new InstantMessageTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test a reminder for right now
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanNowSsml()
        {
            DateTime realStartTime = DateTime.Now;

            string expected = string.Format(CultureInfo.CurrentUICulture, 
                IMResources.LeadTime_Present,
                string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                    realStartTime.ToString("hh:mm", CultureInfo.CurrentUICulture), 
                    realStartTime.ToString("tt", CultureInfo.CurrentUICulture)));
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, DateTime.UtcNow, new SsmlTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder for 1 minute (i.e. singular) from now.
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanOfSingularMinute()
        {
            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Future,
                string.Format(CultureInfo.CurrentUICulture, IMResources.Minutes_Singular, 1.0));
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, DateTime.UtcNow.AddMinutes(1.1), new InstantMessageTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }


        /// <summary>
        /// Test printing the lead time of a reminder for 30 minutes from now
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanOfMinutes()
        {
            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Future,
                string.Format(CultureInfo.CurrentUICulture, IMResources.Minutes_Plural, 30.0));
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, DateTime.UtcNow.AddMinutes(30.0), new InstantMessageTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder over an hour away, but during the same day
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanGreaterThanHour()
        {
            DateTime startTime = DateTime.UtcNow.AddHours(2.5);

            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Today,
                TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local).ToShortTimeString());
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, DateTime.UtcNow.AddHours(2.5), new InstantMessageTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder over an hour away, but during the same day
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanGreaterThanHourSsml()
        {
            DateTime startTime = DateTime.UtcNow.AddHours(2.5);
            DateTime localStartTime = TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local);

            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Today,
                string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                    localStartTime.ToString("hh:mm", CultureInfo.CurrentUICulture), 
                    localStartTime.ToString("tt", CultureInfo.CurrentUICulture)));
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, DateTime.UtcNow.AddHours(2.5), new SsmlTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder that takes place tomorrow
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanTomorrow()
        {
            DateTime startTime = DateTime.UtcNow.AddDays(1.0);

            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Tomorrow,
                TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local).ToString("h:mm tt", CultureInfo.CurrentUICulture));
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, startTime, new InstantMessageTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder that takes place tomorrow
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanTomorrowSsml()
        {
            DateTime startTime = DateTime.UtcNow.AddDays(1.0);
            DateTime realStartTime = TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local);

            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Tomorrow,
                string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                            realStartTime.ToString("hh:mm", CultureInfo.CurrentUICulture),
                            realStartTime.ToString("tt", CultureInfo.CurrentUICulture)));                            
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, startTime, new SsmlTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder that takes place after tomorrow
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanGreaterThanTomorrow()
        {
            DateTime startTime = DateTime.UtcNow.AddHours(60.0);

            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Distant,
                TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local).ToString("dddd, MMMM dd", CultureInfo.CurrentUICulture),
                TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local).ToString("h:mm tt", CultureInfo.CurrentUICulture));
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, startTime, new InstantMessageTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder that takes place after tomorrow
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanGreaterThanTomorrowSsml()
        {
            DateTime startTime = DateTime.UtcNow.AddHours(60.0);
            DateTime realStartTime = TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local);

            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Distant,
                    string.Format(CultureInfo.InvariantCulture, "{1} <say-as type=\"date:md\">{0}</say-as>", realStartTime.ToString("MM-dd", CultureInfo.CurrentUICulture),
                    realStartTime.ToString("dddd", CultureInfo.CurrentUICulture)),
                    string.Format(CultureInfo.InvariantCulture, "<say-as type=\"time\">{0}</say-as> {1}",
                    realStartTime.ToString("hh:mm", CultureInfo.CurrentUICulture), realStartTime.ToString("tt", CultureInfo.CurrentUICulture)));                         
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, startTime, new SsmlTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }

        /// <summary>
        /// Test printing the lead time of a reminder that takes place after tomorrow
        /// </summary>
        [TestMethod()]
        public void TestTimeSpanGreaterThanTomorrowSms()
        {
            DateTime startTime = DateTime.UtcNow.AddHours(60.0);

            string expected = string.Format(CultureInfo.CurrentUICulture,
                IMResources.LeadTime_Distant,
                TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local).ToString("ddd, MMM dd", CultureInfo.CurrentUICulture),
                TimeZoneInfo.ConvertTimeFromUtc(startTime, TimeZoneInfo.Local).ToString("h:mm tt", CultureInfo.CurrentUICulture));
            string actual = DispatcherHelpers.GetLeadTime(CultureInfo.CurrentUICulture, TimeZoneInfo.Local, startTime, new SmsTimeSpanFormatter());

            Assert.AreEqual(expected, actual);
        }
    }
}
